﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Configuration;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Threading;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Communergy.Common;
using CommunergyUploader;
using Communergy.Common.Factories;

namespace Communergy.EnergyMonitor
{
    public class UploadClient
    {
        TimeSpan uploadInterval;

        string meterId;


        List<RealtimeEnergyReading> readingsCache = new List<RealtimeEnergyReading>();

        public UploadClient()
        {
            WriteLog("Starting UploadClient");
            string uploadIntervalConfig = ConfigurationSettings.AppSettings["UploadInterval"];
            uploadInterval = SoapDuration.Parse(uploadIntervalConfig);

            meterId = ConfigurationSettings.AppSettings["MeterId"];
            WriteLog(string.Format("EnergyMonitor config settings: MeterId: {0}, Upload Interval: {1} seconds", meterId,  uploadInterval.TotalSeconds));
            try
            {
                IEnergyMonitorProvider energyMonitorProvider = EnergyMonitorProviderFactory.GetInstance();
                energyMonitorProvider.EnergyReading += new NewReadingHandler(energyMonitorProvider_EnergyReading);
                energyMonitorProvider.StartReadings();

                Thread updaterThread = new Thread(RunUpdater);
                updaterThread.Start();

            }
            catch (Exception ex)
            {
                WriteLog(ex.Message);
            }

        }

        void energyMonitorProvider_EnergyReading(object sender, Communergy.Common.Events.EnergyReadingEventArgs re)
        {
            ICacheManager cache = CacheFactory.GetCacheManager();
            readingsCache = (List<RealtimeEnergyReading>)cache.GetData("readingsCache");
            if (readingsCache == null)
            {
                readingsCache = new List<RealtimeEnergyReading>();
            }
            //lock (readingsCache)
            {
                var newReading = re.RealtimeEnergyReading;
                WriteLog(string.Format("Received new reading at {0}, {1} watts, {2} joules", newReading.ReadingDateTime.ToString(), newReading.Watts, newReading.Joules));
                readingsCache.Add(newReading);
                cache.Add("readingsCache", readingsCache);
            }
        }

        
        /*
        //Take current watts and add to queue
        public void RunReadings()
        {
            while (true)
            {
                try
                {

                    Thread.Sleep((int)readingsInterval.TotalMilliseconds);

                    //TODO - may want to get this some other way
                    int thisWatts = currentWatts;

                    var newReading = new RealtimeEnergyReading
                    {
                        Joules = (int)uploadInterval.TotalSeconds * thisWatts,
                        ReadingDateTime = DateTime.Now,
                        Watts = thisWatts
                    };
                    WriteLog(string.Format("New reading at {0}, {1} watts", newReading.ReadingDateTime.ToString(), newReading.Watts));

                    ICacheManager cache = CacheFactory.GetCacheManager();
                    readingsCache = (List<RealtimeEnergyReading>)cache.GetData("readingsCache");
                    if (readingsCache == null)
                    {
                        
                            readingsCache = new List<RealtimeEnergyReading>();
                        
                    }
                    lock (readingsCache)
                    {
                        readingsCache.Add(newReading);
                        cache.Add("readingsCache", readingsCache);
                    }
                }

                catch (Exception)
                {

                    throw;
                }
            }
        }
         * #
         */
        public void RunUpdater()
        {
            do
            {
                ICacheManager cache = CacheFactory.GetCacheManager();
                {
                    readingsCache = (List<RealtimeEnergyReading>)cache.GetData("readingsCache");
                    if (readingsCache != null && readingsCache.Count > 0)
                    {
                        lock (readingsCache)
                        {
                            try
                            {
                                Stopwatch stopwatch = new Stopwatch();
                                stopwatch.Start();
                                WriteLog(string.Format("Sending {0} records", readingsCache.Count));

                                ICommunergyUpload communergyUpload = CommunergyUploadFactory.GetInstance();
                                communergyUpload.UploadLiveReadings(meterId, readingsCache);
                                stopwatch.Stop();
                                WriteLog(string.Format("Reading sent in {0} ", stopwatch.Elapsed.ToString()));
                      

                                readingsCache = new List<RealtimeEnergyReading>();
                                cache.Add("readingsCache", readingsCache);
                            }
                            catch (Exception updateExcep)
                            {
                                WriteLog(updateExcep.Message);
                            }
                        }
                    }
                }
                Thread.Sleep((int)uploadInterval.TotalMilliseconds);
            } while (true);
        }

        void WriteLog(string message)
        {
            Console.WriteLine(message);
            Trace.WriteLine(message);
        }
    }


}
